#include "Mutex.h"

namespace utils
{

Mutex::Mutex()
{
    ::pthread_mutex_init(&mutex_, nullptr);
}

Mutex::~Mutex()
{
    ::pthread_mutex_destroy(&mutex_);
}

void Mutex::lock()
{
    ::pthread_mutex_lock(&mutex_);
}

void Mutex::unlock()
{
    ::pthread_mutex_unlock(&mutex_);
}
    
RWMutex::RWMutex()
{
    ::pthread_rwlock_init(&mutex_, nullptr);
}

RWMutex::~RWMutex()
{
    ::pthread_rwlock_destroy(&mutex_);
}

void RWMutex::rdlock()
{
    ::pthread_rwlock_rdlock(&mutex_);
}

void RWMutex::wrlock()
{
    ::pthread_rwlock_wrlock(&mutex_);
}

void RWMutex::unlock()
{
    ::pthread_rwlock_unlock(&mutex_);
}

SpinMutex::SpinMutex()
{
    ::pthread_spin_init(&mutex_, 0);
}

SpinMutex::~SpinMutex()
{
    ::pthread_spin_destroy(&mutex_);
}

void SpinMutex::lock()
{
    ::pthread_spin_lock(&mutex_);
}

void SpinMutex::unlock()
{
    ::pthread_spin_unlock(&mutex_);
}

ReadLock::ReadLock(RWMutex& mutex)
        : mutex_(mutex)
{
    lock();
}

ReadLock::~ReadLock()
{
    unlock();
}

void ReadLock::lock()
{
    mutex_.rdlock();
}

void ReadLock::unlock()
{
    mutex_.unlock();
}

WriteLock::WriteLock(RWMutex& mutex)
    : mutex_(mutex)
{
    lock();
}

WriteLock::~WriteLock()
{
    unlock();
}

void WriteLock::lock()
{
    mutex_.wrlock();
}

void WriteLock::unlock()
{
    mutex_.unlock();
}

Semaphore::Semaphore(unsigned int value)
{
    ::sem_init(&m_sem, 0, value);
}

Semaphore::~Semaphore()
{
    ::sem_destroy(&m_sem);
}

void Semaphore::wait()
{
    ::sem_wait(&m_sem);
}

void Semaphore::notify()
{
    ::sem_post(&m_sem);
}
} // namespace utils
